package cn.qayy.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 *DataSource数据源工具类，用于获取数据源
 * 手动开启事务，提交，回滚，关闭资源等
 */
public class DataSourceUtils {
    /***
     * c3p0数据源，需要的配置文件：c3p0.properties或c3p0-config.xml，必须位于classpath路径下
     * new ComboPooledDataSource时会去classpath路径下寻找以上的配置文件。
     */
    private static ComboPooledDataSource ds = new ComboPooledDataSource();
    /***ds数据源对象，tl ThreadLocal对象，维护了一个以当前线程为key的Map集合
     * 常用于把Connection对象绑定到该Map里，保证了当前线程里所有的Connection对象是同一个对象。
     */
    private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();

    /**
     * 从线程中获取连接
     *
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        //从线程中获取conneciton
        Connection conn = tl.get();
        if (conn == null) {
            conn = ds.getConnection();
            //和当前线程绑定
            tl.set(conn);
        }
        return conn;
    }

    // 获取数据源
    public static DataSource getDataSource() {
        return ds;
    }

    // 释放资源
    public static void closeResource(Statement st, ResultSet rs) throws SQLException {
        closeResultSet(rs);
        closeStatement(st);
    }

    // 释放资源
    public static void closeResource(Connection conn, Statement st, ResultSet rs) throws SQLException {
        closeResource(st, rs);
        closeConn(conn);
    }

    // 释放 connection
    public static void closeConn(Connection conn) throws SQLException {
        if (conn != null) {
            conn.close();
            //和线程解绑
            tl.remove();
            conn = null;
        }
    }

    // 释放 statement  idea ctrl + alt + l 格式化代码
    public static void closeStatement(Statement st) throws SQLException {
        if (st != null) {
            st.close();
            st = null;
        }
    }

    // 释放结果集
    public static void closeResultSet(ResultSet rs) throws SQLException {
        if (rs != null) {
            rs.close();
            rs = null;
        }
    }

    //开启事务
    public static void startTransaction() throws SQLException {
        getConnection().setAutoCommit(false);
    }

    /**
     * 事务提交且释放连接
     */
    public static void commitAndClose() throws SQLException {
        Connection conn = getConnection();
        //事务提交
        conn.commit();
        //关闭资源
        conn.close();
        //解除绑定
        tl.remove();
    }

    /**
     * 事务回滚且释放资源
     */
    public static void rollbackAndClose() throws SQLException {
        Connection conn =getConnection();
        //事务回滚
        conn.rollback();
        //关闭资源
        conn.close();
        //解除绑定
        tl.remove();
    }
}